import { history, ErrorShowType, dynamic } from 'umi';
import type { RequestConfig } from 'umi';

import type { Settings as LayoutSettings } from '@ant-design/pro-layout';
import { PageLoading } from '@ant-design/pro-layout';
import {
  getApiCurrentUser as queryCurrentUser,
  getApiCurrentUserRefresh as refreshCurrentUser
} from './services/furion-cms/Account';
import { stringify } from 'querystring';
import { message, notification, Space } from 'antd';
import EventComponent from '@/components/EventSource';
import type { Context } from 'umi-request/types/index'
import { getApiSiteSettingInformation as GetSiteOemInfomation } from './services/furion-cms/siteSetting';

const loginPath = '/admin/login';

/** 获取用户信息比较慢的时候会展示一个 loading */
export const initialStateConfig = {
  loading: <PageLoading />,
};

/**
 * @see  https://umijs.org/zh-CN/plugins/plugin-initial-state
 * */
export async function getInitialState(): Promise<{
  settings?: Partial<LayoutSettings & API.SiteInformationDto>;
  currentUser?: API.UserDto;
  fetchUserInfo?: () => Promise<API.UserDto | undefined>;
  refreshUserInfo?: () => Promise<API.NotDataResult>;
  eventHub?: EventComponent;
}> {

  let defaultSettings = {}
  // 获取网站Oem信息
  try {
    const { data } = await GetSiteOemInfomation({});
    // logo处理
    let appLogo = data?.logo;
    if (!appLogo) {
      appLogo = 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg';
    }
    defaultSettings = {
      ...data,
      logo: appLogo,
    };
  } catch { }

  const fetchUserInfo = async () => {
    try {
      const msg = await queryCurrentUser();
      return msg.data;
    } catch (error) {
      history.push(loginPath);
    }
    return undefined;
  };

  // 如果是登录页面，不执行

  if (history.location.pathname.startsWith('/admin') && history.location.pathname !== loginPath) {
    const currentUser = await fetchUserInfo();
    const eventHub = new EventComponent();
    return {
      fetchUserInfo,
      refreshUserInfo: refreshCurrentUser,
      currentUser,
      settings: {
        ...defaultSettings
      },
      eventHub
    };
  }
  return {
    fetchUserInfo,
    settings: {
      ...defaultSettings
    },
  };
}

// request配置
const authAuthorizationHeaderInterceptor = (url: string, options: RequestConfig) => {
  const accessToken = localStorage.getItem("access-token") || '',
    refreshToken = localStorage.getItem("x-access-token");
  const authHeader = { Authorization: `Bearer ${accessToken}` };
  if (refreshToken) {
    authHeader["X-Authorization"] = `Bearer ${refreshToken}`;
  }
  if (options.headers?.['Content-Type'] == "multipart/form-data") {
    options.beforeRequest?.(options.data);
  }
  console.log('authAuthorizationHeaderInterceptor', options);
  return {
    url: `${url}`,
    options: { ...options, interceptors: true, headers: authHeader },
  };
};

const addOrUpdateTokenInterceptors = (response: Response, options: any) => {
  if ([401, 403].includes(response.status)) {
    const handles = {
      401: () => {
        const { query = {}, pathname } = history.location;
        const { redirect } = query;

        // 清除本地存储
        localStorage.removeItem("access-token");
        localStorage.removeItem("x-access-token");

        // Note: There may be security issues, please note
        if (pathname.startsWith('/admin') && pathname !== loginPath && !redirect) {
          history.replace({
            pathname: loginPath,
            search: stringify({
              redirect: pathname,
            }),
          });
        }
      },
      403: () => {

      }
    }
    console.log('addOrUpdateTokenInterceptors', response.status, options.skipErrorHandler);
    handles[response.status]();
  }
  else {
    const accessToken = response.headers.get("access-token"),
      refreshToken = response.headers.get("x-access-token");

    if (accessToken) {
      localStorage.setItem("access-token", accessToken);
      localStorage.setItem("x-access-token", refreshToken!);
    }
  }

  return response;
};

interface ErrorInfoStructure {
  success: boolean;
  data?: any;
  errorCode?: string;
  errorMessage?: string;
  showType?: ErrorShowType;
  traceId?: string;
  host?: string;
  [key: string]: any;
}

interface RequestError extends Error {
  data?: any;
  info?: ErrorInfoStructure;
  request?: Context['req'];
  response?: Context['res'];
}

const errorHandler = (error: RequestError) => {
  console.log('errorHandler', error?.request?.options);
  // @ts-ignore
  if (error?.request?.options?.skipErrorHandler) {
    throw error;
  }
  const errorInfo = error.data;
  if (errorInfo) {
    const errorMessage = errorInfo?.errorMessage;
    const errorCode = errorInfo?.errorCode;
    const errorPage = '/exception';

    switch (errorInfo?.showType) {
      case ErrorShowType.SILENT:
        // do nothing
        break;
      case ErrorShowType.WARN_MESSAGE:
        message.warn(errorMessage);
        break;
      case ErrorShowType.ERROR_MESSAGE:
        message.error(errorMessage);
        break;
      case ErrorShowType.NOTIFICATION:
        notification.error({
          description: (<Space direction="vertical">{errorInfo.data.map((txt: string, index: number) => (<span key={index.toString()}>{txt}</span>))}</Space>),
          message: errorMessage,
        });
        break;
      case ErrorShowType.REDIRECT:
        // @ts-ignore
        history.push({
          pathname: errorPage,
          query: { errorCode, errorMessage },
        });
        // redirect to error page
        break;
      default:
        message.error(errorMessage);
        break;
    }
  } else {
    message.error(error.message || 'Request error, please retry.');
  }
  throw error;
}

export const request: RequestConfig = {
  // 新增自动添加AccessToken的请求前拦截器
  requestInterceptors: [authAuthorizationHeaderInterceptor],
  responseInterceptors: [addOrUpdateTokenInterceptors],
  errorHandler,
}

// 运行时路由配置,自动检测是否存在默认首页
export function patchRoutes({ routes }: any) {
  const rootRoutes = routes.find((t: any) => t.path === '/')?.routes;
  const adminRootRoutes = rootRoutes?.find((t: any) => t.path === '/admin')?.routes ?? [];
  const children = adminRootRoutes?.find((t: any) => t.path === '/admin')?.routes ?? [];
  const result = children.filter((t: any) => t.path === '/admin/dashboard');
  if (result.length === 0) {
    const startIndex = children.findIndex((t: any) => t.code !== undefined);
    console.log('patchRoutes', JSON.parse(JSON.stringify(routes)), startIndex);
    // 未设置后端控制台时会自动添加一个
    children.splice(startIndex, 0, {
      path: '/admin/dashboard',
      name: 'dashboard',
      icon: 'dashboard',
      exact: true,
      component: dynamic({ loader: () => import('./pages/Dashboard') }),
    });
    children.unshift({
      exact: true,
      path: '/admin',
      redirect: '/admin/dashboard'
    });
    children.unshift({
      exact: true,
      path: '/',
      redirect: '/admin'
    });
  }
}